package com.example.plugindemo

import android.content.Context
import android.content.Context.CONTEXT_IGNORE_SECURITY
import android.content.Context.CONTEXT_INCLUDE_CODE
import android.util.Log
import android.view.View
import com.example.mylibrary.IPluginViewHost
import dalvik.system.DexClassLoader
import dalvik.system.PathClassLoader
import java.io.File
import java.lang.reflect.Constructor


object LoadViewUtil {

    private const val TAG = "LoadViewUtil"

    private const val PLUGIN_PACKAGE = "com.example.myplugin"
    private const val PLUGIN_VIEW_HOST_CLASS = "com.example.myplugin.DemoPluginViewHost"
    private const val PLUGIN_VIEW_CLASS = "com.example.myplugin.MyPluginView"

    fun loadPluginView2(context: Context): View? {
        try {

            val pluginClassLoader = createPluginClassLoader2(context)
            // 获取插件Context
            val pluginContext = createPluginContext2(context, pluginClassLoader)

            // 加载插件中的 View 类
            val viewHostClass = Class.forName(PLUGIN_VIEW_HOST_CLASS, true, pluginClassLoader)
//            val viewHostClass = pluginClassLoader.loadClass(PLUGIN_VIEW_HOST_CLASS)

            // 构造 View，传入插件 Context
            val constructor: Constructor<*> = viewHostClass.getConstructor()
            val pluginViewHost = constructor.newInstance() as IPluginViewHost
            return pluginViewHost.createView(pluginContext)
        } catch (e: Exception) {
            Log.e(TAG, "Error loading plugin view: $e")
        }
        return null
    }

    fun loadPluginView(context: Context): View? {
        try {

            val pluginClassLoader = createPluginClassLoader(context)
            // 获取插件Context
            val pluginContext = createPluginContext(context)

            // 加载插件中的 View 类
            val viewClass = Class.forName(PLUGIN_VIEW_CLASS, true, pluginClassLoader)
//            val viewClass = pluginClassLoader.loadClass(PLUGIN_VIEW_CLASS)

            // 构造 View，传入插件 Context
            val constructor: Constructor<*> = viewClass.getConstructor(Context::class.java)
            val pluginView = constructor.newInstance(pluginContext) as View
            return pluginView
        } catch (e: Exception) {
            Log.e(TAG, "Error loading plugin view: $e")
        }
        return null
    }

    private fun createPluginClassLoader2(context: Context): PathClassLoader {
        // 获取插件 APK 路径
        val appInfo = context.packageManager.getApplicationInfo(PLUGIN_PACKAGE, 0)
        // 1. dex 路径：APK 本体
        val apkPath = appInfo.sourceDir
        // 2. native 库路径（通常为 /data/app-lib/... 或 nativeLibraryDir）
        val libPath = appInfo.nativeLibraryDir

        val classLoader = PathClassLoader(
            apkPath,
            libPath,
            context.classLoader
        )
        return classLoader
    }

    private fun createPluginClassLoader(context: Context): DexClassLoader {
        // 获取插件 APK 路径
        val appInfo = context.packageManager.getApplicationInfo(PLUGIN_PACKAGE, 0)
        // 1. dex 路径：APK 本体
        val apkPath = appInfo.sourceDir
        // 2. native 库路径（通常为 /data/app-lib/... 或 nativeLibraryDir）
        val libPath = appInfo.nativeLibraryDir

        // 创建 DexClassLoader
        val dexOutputDir: File = context.getDir("dex", Context.MODE_PRIVATE)
        val classLoader = DexClassLoader(
            apkPath,
            dexOutputDir.absolutePath,
            libPath,
            context.classLoader
        )
        return classLoader
    }

    private fun createPluginContext2(context: Context, pluginClassLoader: ClassLoader): Context {
        val remoteContext = context.createPackageContext(
            PLUGIN_PACKAGE,
            CONTEXT_INCLUDE_CODE or CONTEXT_IGNORE_SECURITY
        )
        return PluginContext(context, remoteContext, pluginClassLoader)
    }

    private fun createPluginContext(context: Context): Context {
        val remoteContext = context.createPackageContext(
            PLUGIN_PACKAGE,
            CONTEXT_INCLUDE_CODE or CONTEXT_IGNORE_SECURITY
        )
        return remoteContext
    }

}